package com.xiaotu.service.redission.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import com.xiaotu.constant.RedisConstants;
import com.xiaotu.service.redission.RedissionService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;


/**
 * @author zhangxiao
 * @create 2021-08-31 13:29
 */
@Service
public class RedissionServiceImpl implements RedissionService {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public boolean validPhoneAndroidDeviceIdNotice(String phone, String androidDeviceId) {
        RLock rLock = null;
        boolean isNotice = false;
        try {
            rLock = redissonClient.getLock(androidDeviceId);
            boolean tryLock = rLock.tryLock(1, 3, TimeUnit.SECONDS);
            if (tryLock) {
                String key = RedisConstants.getPhoneBindAndroidDeviceIdKey(phone);
                if (redisTemplate.hasKey(key)) {
                    String oldDeviceId = (String) redisTemplate.opsForValue().get(key);
                    if (androidDeviceId.equals(oldDeviceId)) {
                        isNotice = false;
                    } else {
                        isNotice = true;
                    }
                }
                //设置
                redisTemplate.opsForValue().set(key, androidDeviceId);
                redisTemplate.expire(key, RedisConstants.PHONE_BIND_ANDROID_DEVICEID_EXPIRE_TIME, TimeUnit.MILLISECONDS);
            } else {
                Validator.validateTrue(Boolean.FALSE, "网络繁忙，请稍后重试!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //TODO:释放锁
            if (ObjectUtil.isNotNull(rLock) && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
        return isNotice;
    }

    @Override
    public void setPhoneAndroidDeviceId(String phone, String androidDeviceId) {
        RLock rLock = null;
        try {
            rLock = redissonClient.getLock(androidDeviceId);
            boolean tryLock = rLock.tryLock(1, 3, TimeUnit.SECONDS);
            if (tryLock) {
                String key = RedisConstants.getPhoneBindAndroidDeviceIdKey(phone);
                redisTemplate.opsForValue().set(key, androidDeviceId);
                redisTemplate.expire(key, RedisConstants.EXPIRE_TIME, TimeUnit.MILLISECONDS);
            } else {
                Validator.validateTrue(Boolean.FALSE, "网络繁忙，请稍后重试!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //TODO:释放锁
            if (ObjectUtil.isNotNull(rLock) && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
    }

    @Override
    public void setPhoneToken(String phone, String token) {
        RLock rLock = null;
        try {
            rLock = redissonClient.getLock(phone);
            boolean tryLock = rLock.tryLock(1, 3, TimeUnit.SECONDS);
            if (tryLock) {
                String key = RedisConstants.getLoginUserKey(phone);
                redisTemplate.opsForValue().set(key, token);
                redisTemplate.expire(key, RedisConstants.EXPIRE_TIME, TimeUnit.MILLISECONDS);
            } else {
                Validator.validateTrue(Boolean.FALSE, "网络繁忙，请稍后重试!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //TODO:释放锁
            if (ObjectUtil.isNotNull(rLock) && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
    }

    @Override
    public boolean validPhoneToken(String phone, String token) {
        RLock rLock = null;
        boolean isValid = false;
        try {
            rLock = redissonClient.getLock(phone);
            boolean tryLock = rLock.tryLock(1, 3, TimeUnit.SECONDS);
            if (tryLock) {
                String key = RedisConstants.getLoginUserKey(phone);
                if (redisTemplate.hasKey(key)) {
                    String oldToken = (String) redisTemplate.opsForValue().get(key);
                    if (token.equals(oldToken)) {
                        isValid = true;
                    } else {
                        isValid = false;
                    }
                } else {
                    isValid = false;
                }
            } else {
                Validator.validateTrue(Boolean.FALSE, "网络繁忙，请稍后重试!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //TODO:释放锁
            if (ObjectUtil.isNotNull(rLock) && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
        return isValid;
    }

    @Override
    public void setNickNameEffectiveTime(Integer playerId) {
        RLock rLock = null;
        try {
            rLock = redissonClient.getLock(String.valueOf(playerId));
            boolean tryLock = rLock.tryLock(1, 3, TimeUnit.SECONDS);
            if (tryLock) {
                String key = RedisConstants.getRefreshNickNameKey(playerId);
                redisTemplate.opsForValue().set(key, null);
                redisTemplate.expire(key, RedisConstants.REFRESH_NICK_NAME_EXPIRE_TIME, TimeUnit.SECONDS);
            } else {
                Validator.validateTrue(Boolean.FALSE, "网络繁忙，请稍后重试!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //TODO:释放锁
            if (ObjectUtil.isNotNull(rLock) && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
    }

    @Override
    public boolean validNickNameEffective(Integer playerId) {
        RLock rLock = null;
        boolean isValid = false;
        try {
            rLock = redissonClient.getLock(String.valueOf(playerId));
            boolean tryLock = rLock.tryLock(1, 3, TimeUnit.SECONDS);
            if (tryLock) {
                String key = RedisConstants.getRefreshNickNameKey(playerId);
                if (redisTemplate.hasKey(key)) {
                    isValid = false;
                } else {
                    isValid = true;
                }
            } else {
                Validator.validateTrue(Boolean.FALSE, "网络繁忙，请稍后重试!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //TODO:释放锁
            if (ObjectUtil.isNotNull(rLock) && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
        return isValid;
    }

}
